package com.yfbao.web.pdf.utils;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.yfbao.web.pdf.dto.ModificationDto;

import java.awt.*;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PdfFileUtil {

    public static void analyzePdfProtection(String filePath) {
        try {
            PdfReader reader = new PdfReader(filePath);

            System.out.println("=== 详细保护分析 ===");
            System.out.println("加密: " + reader.isEncrypted());
            System.out.println("被保护: " + reader.isOpenedWithFullPermissions());
            System.out.println("权限值: " + reader.getPermissions());

            // 详细权限分析
            analyzePermissions(reader.getPermissions());

            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void analyzePermissions(long permissions) {
        System.out.println("=== 具体权限 ===");
        System.out.println("允许打印: " + ((permissions & PdfWriter.ALLOW_PRINTING) != 0));
        System.out.println("允许修改内容: " + ((permissions & PdfWriter.ALLOW_MODIFY_CONTENTS) != 0));
        System.out.println("允许复制: " + ((permissions & PdfWriter.ALLOW_COPY) != 0));
        System.out.println("允许修改注释: " + ((permissions & PdfWriter.ALLOW_MODIFY_ANNOTATIONS) != 0));
        System.out.println("允许填写表单: " + ((permissions & PdfWriter.ALLOW_FILL_IN) != 0));
        System.out.println("允许提取内容: " + ((permissions & PdfWriter.ALLOW_SCREENREADERS) != 0));
        System.out.println("允许组装: " + ((permissions & PdfWriter.ALLOW_ASSEMBLY) != 0));

        // 检查是否是只读保护
        if ((permissions & PdfWriter.ALLOW_MODIFY_CONTENTS) == 0) {
            System.out.println("⚠️  PDF被设置为只读，禁止修改内容");
        }
    }








    public static boolean bypassProtectionByFlag(String sourcePath, String destPath) {
        try {
            // 即使有保护也强制打开
            PdfReader reader = new PdfReader(sourcePath);

            // 关键：使用反射修改权限标志（谨慎使用）
            try {
                java.lang.reflect.Field f = reader.getClass().getDeclaredField("encrypted");
                f.setAccessible(true);
                f.set(reader, false);

                f = reader.getClass().getDeclaredField("ownerPassword");
                f.setAccessible(true);
                f.set(reader, new byte[0]);

            } catch (Exception e) {
                System.out.println("反射修改失败，尝试其他方法");
            }

            // 创建新的PDF
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 关键：不设置任何保护
            // stamper.setEncryption(null, null, 0, 0);

            // 现在可以自由编辑
            editPdfContent(stamper);

            stamper.close();
            reader.close();

            System.out.println("权限绕过成功");
            return true;

        } catch (Exception e) {
            System.err.println("方法1失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 方法2：重新设置完整权限
     */
    public static boolean resetPermissions(String sourcePath, String destPath) {
        try {
            PdfReader reader = new PdfReader(sourcePath);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 重新设置所有权限（关键步骤）
            stamper.setEncryption(
                    null, // 用户密码 - 设为null表示不需要密码
                    null, // 所有者密码 - 设为null表示完全开放
                    PdfWriter.ALLOW_PRINTING |
                            PdfWriter.ALLOW_MODIFY_CONTENTS |
                            PdfWriter.ALLOW_COPY |
                            PdfWriter.ALLOW_MODIFY_ANNOTATIONS |
                            PdfWriter.ALLOW_FILL_IN |
                            PdfWriter.ALLOW_SCREENREADERS |
                            PdfWriter.ALLOW_ASSEMBLY,
                    PdfWriter.STANDARD_ENCRYPTION_128
            );

            editPdfContent(stamper);
            stamper.close();
            reader.close();

            return true;

        } catch (Exception e) {
            System.err.println("方法2失败: " + e.getMessage());
            return false;
        }
    }

    private static void editPdfContent(PdfStamper stamper) {
        try {
            for (int i = 1; i <= stamper.getReader().getNumberOfPages(); i++) {
                PdfContentByte canvas = stamper.getOverContent(i);

                // 添加测试文本确认可编辑
                canvas.beginText();
                BaseFont baseFont = BaseFont.createFont(
                        BaseFont.HELVETICA_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
                canvas.setFontAndSize(baseFont, 12);
                canvas.setRGBColorFill(255, 0, 0);
                canvas.setTextMatrix(50, 50);
                canvas.showText("yyy-你好-dd22-11 " + new Date());
                canvas.endText();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static void modificationPdf(String sourcePath, String destPath, List<ModificationDto> editList) {
        try {
            PdfReader reader = new PdfReader(sourcePath);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 重新设置所有权限（关键步骤）
            stamper.setEncryption(
                    null, // 用户密码 - 设为null表示不需要密码
                    null, // 所有者密码 - 设为null表示完全开放
                    PdfWriter.ALLOW_PRINTING |
                            PdfWriter.ALLOW_MODIFY_CONTENTS |
                            PdfWriter.ALLOW_COPY |
                            PdfWriter.ALLOW_MODIFY_ANNOTATIONS |
                            PdfWriter.ALLOW_FILL_IN |
                            PdfWriter.ALLOW_SCREENREADERS |
                            PdfWriter.ALLOW_ASSEMBLY,
                    PdfWriter.STANDARD_ENCRYPTION_128
            );

            for (ModificationDto modificationDto : editList) {
                editPdfContent(stamper,modificationDto);
            }
            stamper.close();
            reader.close();

            return ;

        } catch (Exception e) {
            System.err.println("方法2失败: " + e.getMessage());
            return ;
        }
    }

    private static void editPdfContent(PdfStamper stamper,ModificationDto editInfo) {
        try {
            for (int i = 1; i <= stamper.getReader().getNumberOfPages(); i++) {
                PdfContentByte canvas = stamper.getOverContent(i);

                // 添加测试文本确认可编辑
                canvas.beginText();
                BaseFont baseFont = BaseFont.createFont(
                        BaseFont.HELVETICA_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
                canvas.setFontAndSize(baseFont, 12);
                canvas.setRGBColorFill(255, 0, 0);
                canvas.setTextMatrix(50, 50);
                canvas.showText("yyy-你好-dd22-11 " + new Date());
                canvas.endText();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void modificationPdf_normal(String sourcePath, String destPath) {
        PdfReader reader = null;
        PdfStamper stamper = null;

        try {
            reader = new PdfReader(sourcePath);
            stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 重新设置所有权限
            stamper.setEncryption(
                    null, // 用户密码
                    null, // 所有者密码
                    PdfWriter.ALLOW_PRINTING |
                            PdfWriter.ALLOW_MODIFY_CONTENTS |
                            PdfWriter.ALLOW_COPY |
                            PdfWriter.ALLOW_MODIFY_ANNOTATIONS |
                            PdfWriter.ALLOW_FILL_IN |
                            PdfWriter.ALLOW_SCREENREADERS |
                            PdfWriter.ALLOW_ASSEMBLY,
                    PdfWriter.STANDARD_ENCRYPTION_128
            );

            // 按页码分组处理，提高效率
            PdfContentByte canvas = stamper.getOverContent(1);
            applyTextModification(canvas,stamper);

        } catch (Exception e) {
            System.err.println("PDF修改失败: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 确保资源关闭
            try {
                if (stamper != null) {
                    stamper.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (Exception e) {
                System.err.println("关闭资源时出错: " + e.getMessage());
            }
        }
    }

    private static void applyTextModification(PdfContentByte canvas, PdfStamper stamper) {
        try {
// 绘制白色矩形覆盖原内容
            //(113, 115)
            //width 105
            // height 13
            canvas.setRGBColorFill(255, 255, 255); // 白色
            canvas.setColorFill(BaseColor.WHITE);
            Rectangle pageSize = stamper.getReader().getPageSize(1);

            float xStart = 113;
//            float xEnd = xStart+105;
            float yStart = pageSize.getHeight()-115-13;
//            float yEnd = yStart-13;
            canvas.rectangle(
                    xStart,
                    yStart,
                    105,
                    13
            );
            canvas.fill();


            canvas.saveState(); // 保存图形状态

            // 设置字体
            BaseFont baseFont = BaseFont.createFont(
                    BaseFont.HELVETICA_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
            canvas.setFontAndSize(baseFont, 12);
            canvas.setRGBColorFill(255, 0, 0);

            // 开始文本操作
            canvas.beginText();

            // 设置文本位置（PDF坐标系：左下角为原点）113, 115
            float x = 113;

            float y = pageSize.getHeight()-115-12;

            canvas.setTextMatrix(x, y);

            // 显示文本
            canvas.showText("AAAAAAA");

            canvas.endText();
            canvas.restoreState(); // 恢复图形状态

            System.out.println("成功应用文本修改:  在位置(" + x + ", " + y + ")");

        } catch (Exception e) {
            System.err.println("文本修改失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String srcFile ="D:\\下载\\bbb.pdf";
//        analyzePdfProtection(srcFile);

//        String destFile = "D:\\下载\\bbb_unprotected.pdf";
//        bypassProtectionByFlag(srcFile, destFile);

//        analyzePdfProtection(destFile);
        String destFile2 = "D:\\下载\\bbb_unprotected2222.pdf";
//        resetPermissions(srcFile,destFile2);

        modificationPdf_normal(srcFile,destFile2);
    }
}
